﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SocketHttpLib
{
    public class Connection 
    {
        public Connection(IPAddress ip, int port)
        {
            this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ;
            this.Ip = ip;
            this.Port = port;
            WaitHandle = new ManualResetEvent(false);
        }
        private ManualResetEvent WaitHandle;
        public Thread ConnectThread;
        public Socket Socket { get; set; }
        public IPAddress Ip { get; set; }
        public int Port { get; set; }
        public Exception Error { get; set; }
        public bool IsSocketError { get; set; }
        public bool IsConnected { get; set; }
        public bool IsCompleted { get; set; }
        public void ConnectAndWait(int millisecondsTimeout)
        {
            ConnectThread = new Thread(() =>
            {
                try
                {
                    Socket.Connect(Ip, Port);
                    IsConnected = Socket.Connected;
                }
                catch (Exception ex)
                {
                    Error = ex;
                }
                IsCompleted = true;
                WaitHandle.Set();
            })
            { IsBackground = true, Name = "CONNECT " + Ip + ":" + Port };
            ConnectThread.Start();
            if (!WaitHandle.WaitOne(millisecondsTimeout))
            {
                try
                {
                    this.ConnectThread.Abort();
                    if (this.Socket.Connected)
                    {
                        this.Socket.Close();
                        this.Socket = null;
                    }
                }
                catch { }
                this.ConnectThread = null;
            }
            WaitHandle.Dispose();
            WaitHandle = null;
            if (this.Error != null)
                throw this.Error;
        }
    }
}
